package com.songcan.oauth.provider;

import com.songcan.common.exception.InvalidException;
import com.songcan.common.utils.SimpleHash;

import com.songcan.common.vo.UserDetailsNew;
import com.songcan.oauth.compent.OauthUserDetailsService;
import com.songcan.oauth.other.CoreLoginAuthenticationToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.*;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Component;


@Component("saltDaoAuthenticationProvider")
@Slf4j
public class SaltDaoAuthenticationProvider extends DaoAuthenticationProvider {



    public SaltDaoAuthenticationProvider(OauthUserDetailsService oauthUserDetailsService){
        super.setUserDetailsService(oauthUserDetailsService);
        super.setPasswordEncoder(passwordEncoder());
    }



    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) {
        if (userDetails == null) {
            throw new UsernameNotFoundException("用户不存在");
        } else if (!userDetails.isAccountNonExpired()) {
            throw new AccountExpiredException(messages.getMessage("account_token_expired", "账户token已过期"));
        } else if (!userDetails.isAccountNonLocked()) {
            throw new LockedException("账户已锁");
        } else if (!userDetails.isCredentialsNonExpired()) {
            logger.debug("User account credentials have expired");
            throw new InvalidException("账号未启用");
        }else if(!userDetails.isEnabled()){
             throw new CredentialsExpiredException(messages.getMessage(
                    "account_unregister",
                    "账号未激活"));
        }

        if (authentication.getCredentials() == null) {
            logger.debug("Authentication failed: no credentials provided");

            throw new BadCredentialsException("密码为空");
        }

        String presentedPassword = authentication.getCredentials().toString();
        Boolean isMatch = false;
        String storedPassword = userDetails.getPassword();
        if (userDetails instanceof UserDetailsNew) {
            String salt = ((UserDetailsNew) userDetails).getSalt();
            SimpleHash simpleHash = new SimpleHash(SimpleHash.AlgorithmName.SHA256, presentedPassword, salt, 0);
            isMatch = storedPassword.equals(simpleHash.toHex());
        } else {
            isMatch = presentedPassword.equals(storedPassword);
        }
        if (!isMatch) {
            logger.debug("Authentication failed: password does not match stored value");
            throw new BadCredentialsException("输入密码错误");
        }
    }

    /**
     * 根据token类型，来判断使用哪个Provider
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                return String.valueOf(rawPassword);
            }
            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return encodedPassword.equals(String.valueOf(rawPassword));
            }
        };
    }

}
